#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
const int N=1e5+300;
struct node{
    int L;
    int R;
};
node w[N];
int WL[N];
int cnt=0,YSE;

int T,s,t;
int n,m,L,V,lf,rt,mid;
int d[N],v[N],a[N];
int p[N];
bool h[N];
int LF,RT,t2,ans=0;
void solve1(){
    s=0;
    for(int i=1;i<=n;i++){
        if(a[i]>=0){
            if(p[m]<d[i]) continue;
            if((((p[m]-d[i])*a[i])<<1)+v[i]*v[i]>V*V){
                h[i]=1;
                s++;
            }
        }else{
            t=p[lower_bound(p+1,p+m+1,d[i])-p];
            if(t==-1) continue;
            if((((t-d[i])*a[i])<<1)+v[i]*v[i]>V*V){
                h[i]=1;
                s++;
            }
        }
    }
    printf("%lld ",s);
    YSE=s;
}
int findR(int id){
    lf=1,rt=m;
    while(lf<=rt){
        mid=(lf+rt)>>1;
        if((((p[mid]-d[id])*a[id])<<1)+v[id]*v[id]>V*V){
            lf=mid+1;
        }else rt=mid-1;
    }
    return lf-1;
}
int findL(int id){
    lf=1,rt=m;
    while(lf<=rt){
        mid=(lf+rt)>>1;
        if((((p[mid]-d[id])*a[id])<<1)+v[id]*v[id]>V*V){
            rt=mid-1;
        }else lf=mid+1;
    }
    return rt+1;
}
bool cmp(node x,node y){
    if(x.L!=y.L) return x.L<y.L;
    return x.R<y.R;
}

void solve2(){
    if(YSE==0){
        printf("%lld\n",m);
        return;
    }
    cnt=0;
    ans=0;
    LF=-1,RT=m+100;
    for(int i=1;i<=n;i++){
        if(h[i]==0) continue;
        if(a[i]>=0){
            //printf("#%d %d\n",findL(i),m);
            //[t,m]
            t=findL(i);
            if(t>m) continue;
            //printf("#%d %d\n",t,m);
            /*if(RT<t||LF>m||LF>RT){
                ans++;
                LF=-1;
                RT=m+100;
            }
            LF=max(LF,t);
            RT=min(RT,m);
            */
            cnt++;
            w[cnt].L=t;
            w[cnt].R=m;
            WL[cnt]=t;
        }else{
            //printf("#%d %d\n",1,findR(i));
            t=findR(i);
            if(t<1) continue;
            
            t2=lower_bound(p+1,p+m+1,d[i])-p;
            if(t2>m) continue;
            /*if(RT<t2||LF>t||LF>RT){
                ans++;
                LF=-1;
                RT=m+100;
            }
            LF=max(LF,t2);
            RT=min(RT,t);*/

            //printf("#%d %d\n",t2,t);
            //[t2,t];
            cnt++;
            w[cnt].L=t2;
            w[cnt].R=t;
            WL[cnt]=t2;
        }
    }
    sort(w+1,w+cnt+1,cmp);
    for(int i=1;i<=cnt;i++){
        if(RT<w[i].L||LF>w[i].R){
            ans++;
            LF=w[i].L;
            RT=w[i].R;
        }
        LF=max(LF,w[i].L);
        RT=min(RT,w[i].R);
        
    }
    
    printf("%lld\n",m-(ans)-1);
}

signed main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    T=read();
    while(T--){
        //init();
        n=read();
        m=read();
        L=read();
        V=read();
        for(int i=1;i<=n;i++){
            d[i]=read();
            v[i]=read();
            a[i]=read();
        }
        for(int i=1;i<=m;i++){
            p[i]=read();
        }
        p[m+1]=-1;
        for(int i=1;i<=n;i++) h[i]=0;
        solve1();
        solve2();
    }
    return 0;
}

/*
1
5 5 15 3
0 3 0
12 4 0
1 1 4
5 5 -2
6 4 -4
2 5 8 9 15

*/